//TODO:  Parse index, unique parameters and send them somewhere else

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace ghostDBscript.Engine.Commands
{
    /// <summary>
    /// Represents a column in database
    /// </summary>
    public class ColumnAdd : ICommand
    {
        #region Properties

        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private SqlDbType _type;
        public SqlDbType Type
        {
            get { return _type; }
            set { _type = value; }
        }

        private int _length = 0;
        public int Length
        {
            get { return _length; }
            set { _length = value; }
        }

        private bool _isPrimaryKey = false;
        public bool IsPrimaryKey
        {
            get { return _isPrimaryKey; }
            set { _isPrimaryKey = value; }
        }

        private bool _isNullable = true;
        public bool IsNullable
        {
            get { return _isNullable; }
            set { _isNullable = value; }
        }
        
        #endregion

        /// <summary>
        /// ctor
        /// </summary>
        public ColumnAdd(string unparsedString)
        {
            //TODO: Move all logic out of the constructor.  Feel really
            // uncomfortable with exceptionable code in the ctor.

            if (unparsedString.Contains(" "))
                _name = unparsedString.Substring(0, unparsedString.IndexOf(" "));
            else
                _name = unparsedString;

            // Default type is varchar, later assigned 50 if no length specified
            _type = SqlDbType.VarChar;

            if (unparsedString.Contains("{") && unparsedString.Contains("}"))
            {
                int left = unparsedString.IndexOf('{');
                int right = unparsedString.IndexOf('}');
                if (right-1 > left)
                    ParseParameters(unparsedString.Substring(left + 1, right - left - 1));
            }
        }

        private void ParseParameters(string parameters)
        {
            string[] paramSplit = parameters.Split(',');

            foreach (string p in paramSplit)
            {
                string par = p.Trim().ToLower();
                if (par.Contains(":length"))
                {
                    int length;
                    if (int.TryParse(par.Substring(par.IndexOf(":length") + 8), out length))
                        _length = length;
                }

                if (par.Contains(":type"))
                {
                    if (par.Contains("datetime"))
                        _type = SqlDbType.DateTime;

                    if (par.Contains("int"))
                        _type = SqlDbType.Int;

                    if (par.Contains("float"))
                        _type = SqlDbType.Float;

                    if (par.Contains("char"))
                        _type = SqlDbType.Char;
                }


                if (par.Contains("not null"))
                    _isNullable = false;
            }

            if (_length == 0 && _type != null &&
                  (_type == SqlDbType.VarChar || _type == SqlDbType.NVarChar))
                _length = 50;

            if (_length == 0 && _type != null &&
                  (_type == SqlDbType.Char || _type == SqlDbType.NChar))
                _length = 5;



        }

        public string ToCommandText()
        {
            StringBuilder builda = new StringBuilder();
            builda.Append("  [");
            builda.Append(_name);
            builda.Append("] ");
            builda.Append(_type.ToString().ToLower());
            builda.Append(" ");

            if (_length > 0)
                builda.Append("(" + _length.ToString() + ") ");
            else
            {
                //TODO:  code dup
                if (_type != null && (_type == SqlDbType.VarChar || _type == SqlDbType.NVarChar))
                    builda.Append("(50) ");
            }

            if (!_isNullable)
                builda.Append("NOT NULL ");

            if (_isPrimaryKey)
                builda.Append("PRIMARY KEY ");

            // Remove last (trailing) space
            builda.Remove(builda.Length - 1, 1);

            return builda.ToString();
        }

        public bool IsValid()
        {
            if (_name == null || _name.Length < 1 ||
                _type == null)
                return false;
            else
                return true;
        }

        private ColumnAdd(bool answer)
        {
            _type = SqlDbType.Int;
            _name = "ID";
            _isPrimaryKey = true;
            _isNullable = false;
        }

        public static ColumnAdd GetIDColumn()
        {
            return new ColumnAdd(true);
        }
    }
}
